package cn.edu.ncut.cs.springboot.petmanagementsystem.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * Spring Security 配置类（JWT 无状态鉴权）
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 关闭 CSRF（前后端分离项目必须关闭）
                .csrf(csrf -> csrf.disable())
                // 开启 CORS（允许跨域）
                .cors(Customizer.withDefaults())
                // 设置无状态 session
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 鉴权规则
                // 注意：Spring Security 6.x 中，当设置了context-path时，路径匹配是基于servlet path（不包含context-path）
                // 但是某些情况下可能需要使用完整路径，这里使用两种方式都匹配
                .authorizeHttpRequests(auth -> auth
                        // 匹配servlet path（不包含context-path的路径）
                        .requestMatchers("/auth/**").permitAll()   // 登录注册等接口放行
                        .requestMatchers("/user/register").permitAll() // 用户注册接口放行
                        .requestMatchers("/public/**").permitAll() // 静态资源或公开接口
                        .requestMatchers("/sale-pet/list").permitAll() // 查询待售宠物列表（公开接口）
                        .requestMatchers("/sale-pets/**").permitAll() // 待售宠物模块公开接口（新路径）
                        .requestMatchers("/pet/list").permitAll() // 查询宠物列表（公开接口）
                        .requestMatchers("/pet/*/").permitAll() // 查询单个宠物详情（公开接口）
                        .requestMatchers("/pet/detail/*").permitAll() // 查询宠物详情（公开接口）
                        .requestMatchers("/pet-health/list").permitAll() // 查询健康记录列表（公开接口）
                        .requestMatchers("/pet-health/detail/*").permitAll() // 查询健康记录详情（公开接口）
                        .requestMatchers("/pet-care/list").permitAll() // 查询护理记录列表（公开接口）
                        .requestMatchers("/pet-care/detail/*").permitAll() // 查询护理记录详情（公开接口）
                        .requestMatchers("/product/list").permitAll() // 查询商品列表（公开接口）
                        // 管理后台接口（需要认证，但先放行用于测试）
                        .requestMatchers("/pet/admin/list", "/admin/pet/list").permitAll() // 管理后台宠物列表
                        .requestMatchers("/pet-care/admin/list", "/admin/pet-care/list").permitAll() // 管理后台护理记录列表
                        .requestMatchers("/pet-health/admin/list", "/admin/pet-health/list").permitAll() // 管理后台健康检测列表
                        .requestMatchers("/sale-pets/admin/list", "/admin/sale-pets/list").permitAll() // 管理后台待售宠物列表
                        .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/index.html").permitAll() // Swagger文档接口放行
                        .requestMatchers("/ws/**").permitAll() // WebSocket HTTP端点放行
                        .requestMatchers("/error").permitAll() // 错误页面放行
                        .requestMatchers("/favicon.ico").permitAll() // Favicon放行
                        // 同时也匹配完整路径（包含context-path），以防万一
                        .requestMatchers(
                            new AntPathRequestMatcher("/api/auth/**"),
                            new AntPathRequestMatcher("/api/user/register"),
                            new AntPathRequestMatcher("/api/public/**"),
                            new AntPathRequestMatcher("/api/sale-pet/list"),
                            new AntPathRequestMatcher("/api/sale-pets/**"),
                            new AntPathRequestMatcher("/api/pet/list"),
                            new AntPathRequestMatcher("/api/pet/*/"),
                            new AntPathRequestMatcher("/api/pet/detail/*"),
                            new AntPathRequestMatcher("/api/pet-health/list"),
                            new AntPathRequestMatcher("/api/pet-health/detail/*"),
                            new AntPathRequestMatcher("/api/pet-care/list"),
                            new AntPathRequestMatcher("/api/pet-care/detail/*"),
                            new AntPathRequestMatcher("/api/product/list"),
                            // 管理后台接口（需要认证，但先放行用于测试）
                            new AntPathRequestMatcher("/api/pet/admin/list"),
                            new AntPathRequestMatcher("/api/admin/pet/list"),
                            new AntPathRequestMatcher("/api/pet-care/admin/list"),
                            new AntPathRequestMatcher("/api/admin/pet-care/list"),
                            new AntPathRequestMatcher("/api/pet-health/admin/list"),
                            new AntPathRequestMatcher("/api/admin/pet-health/list"),
                            new AntPathRequestMatcher("/api/sale-pets/admin/list"),
                            new AntPathRequestMatcher("/api/admin/sale-pets/list"),
                            new AntPathRequestMatcher("/api/swagger-ui/**"),
                            new AntPathRequestMatcher("/api/v3/api-docs/**"),
                            new AntPathRequestMatcher("/api/ws/**"),
                            new AntPathRequestMatcher("/api/error"),
                            new AntPathRequestMatcher("/api/favicon.ico")
                        ).permitAll()
                        .anyRequest().authenticated()              // 其余接口都需要认证
                )
                // 在 UsernamePasswordAuthenticationFilter 之前添加 JWT 过滤器
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    /**
     * 密码加密器（登录时使用）
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 认证管理器（用于登录认证）
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
}
